#include "Table.h"

void InitTable(Table &table) {
	table.currentTurn = 0;
	InitTableCards(table);
	InitPlayers(table, 2);
	table.currentPlayer = 0;
	table.blind = 10;
	table.turnLoop = 0;
	table.totalBet = 0;
}

void InitTableCards(Table &tableCards) {
	tableCards.currentCardNb = 0;
	InitDeck(tableCards.deck);
	InitIndex(tableCards.deckIndex);
}

void InitPlayers(Table &tablePlayers, int playerNumber) {
	tablePlayers.currentPlayerNb = playerNumber;
	for (int i = 0; i < playerNumber; i++) {
		InitPlayer(tablePlayers.players[i]);
	}
}

void DisplayTableCards(const Table &table) {
	std::cout << "Current card on the table" << std::endl;
	for (int i = 0; i < 7; i++) {
		for (int j = 0; j < table.currentCardNb; j++) {
			ShowRow(table.playCard[j], i); 
		}
		std::cout << std::endl;
	}
}

void DisplayPlayerHand(const Player &player) {
	std::cout << "The cards you hold in your hand" << std::endl;
	for (int i = 0; i < 7; i++) {
		for (int j = 0; j < player.hand.nb; j++) {
			ShowRow(player.hand.cards[j], i);
		}
		std::cout << std::endl;
	}
}

void GiveHand(Player &player, const Deck &deck, DeckIndex &deckIndex) {
	for (int i = 0; i < HAND_MAX_NUMBER; i++) {
		GetCard(player.hand.cards[i], deck, deckIndex);
		player.hand.nb++;
	}
}

void CheckHands(Table &table) {
	Card allCards[7];
	for (int iPlayer = 0; iPlayer < table.currentPlayerNb; iPlayer++) {
		if (table.players[iPlayer].state == IN) {
			SortCards(allCards, table, table.players[iPlayer]);
			table.PlayerScore[iPlayer] = GetHandScore(allCards);
			std::cout << iPlayer << " score : " << table.PlayerScore[iPlayer] << std::endl;
		}
	}
}

void SortCards(Card (&allCards)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER], const Table &table, const Player &player) {
	int allCardNb = 0;
	bool hasChanged = true;
	for (int iCount = 0; iCount < table.currentCardNb; iCount++) {
		allCards[iCount] = table.playCard[iCount];
		allCardNb++;
	}
	for (int iCount = 0; iCount < HAND_MAX_NUMBER; iCount++) {
		allCards[iCount + table.currentCardNb] = player.hand.cards[iCount];
		allCardNb++;
	}
	//Sort Value from Highest to Lowest
	while (hasChanged) {
		hasChanged = false;
		for (int iCount = 0; iCount < allCardNb - 1; iCount++) {
			if (allCards[iCount].value < allCards[iCount + 1].value) {
				Card temp = allCards[iCount];
				allCards[iCount] = allCards[iCount + 1];
				allCards[iCount + 1] = temp;
				hasChanged = true;
			}
		}
	}
	hasChanged = true;
	//Sort same value by kind
	while (hasChanged) {
		hasChanged = false;
		for (int iCount = 0; iCount < allCardNb - 1; iCount++) {
			if (allCards[iCount].value == allCards[iCount + 1].value) {
				if (allCards[iCount].kind > allCards[iCount + 1].kind) {
					Card temp = allCards[iCount];
					allCards[iCount] = allCards[iCount + 1];
					allCards[iCount + 1] = temp;
					hasChanged = true;
				}
			}
		}
	}
}

int GetHandScore(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]) {
	if (hasStraightFlush(card)) {
		return STRAIGHT_FLUSH;
	} else if (hasFourOfKind(card)) {
		return KIND4;
	} else if (hasFullHouse(card)) {
		return FULL_HOUSE;
	} else if (hasFlush(card)) {
		return FLUSH;
	} else if (hasStraight(card)) {
		return STRAIGHT;
	} else if (hasThreeOfKind(card)) {
		return KIND3;
	} else if (hasTwoPairs(card)) {
		return PAIR2;
	} else if (hasPair(card)) {
		return PAIR;
	} else {
		return HIGHCARD + card[0].value;
	}
}

void GetWinners(const Table &table, int(&winnerIndex)[PLAYER_MAX_NUMBER], int &nbWinner) {
	int temp = 0;
	nbWinner = 0;
	for (int i = 0; i < table.currentPlayerNb; i++) {
		if (table.PlayerScore[i] > temp && table.players[i].state == IN) {
			temp = table.PlayerScore[i];
		}
	}
	for (int i = 0; i < table.currentPlayerNb; i++) {
		if (table.PlayerScore[i] == temp && table.players[i].state == IN) {
			winnerIndex[nbWinner] = i;
			nbWinner++;
		}
	}
}

bool hasStraightFlush(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	int straightF = 0;
	int flush = 0;
	Card cardsTemp[5];
	for (int i = 0; i < 6 && straightF < 4; i++) {
		if (card[i].value == (card[i + 1].value + 1)) {
			cardsTemp[straightF] = card[i];
			straightF++;
		} else {
			straightF = 0;
		}
	}
	for (int i = 0; i < 6 && flush < 4 && straightF >= 4; i++) {
		flush = 0;
		for (int j = 0; j < 7; j++) {
			if (card[i].kind == card[j].kind && j != i) {
				flush++;
			}
		}
	}
	return straightF >= 4 && flush >= 4;
}

bool hasFourOfKind(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	int fourKind = 0;
	for (int i = 0; i < 6 && fourKind < 3; i++) {
		if (card[i].value == card[i + 1].value) {
			fourKind++;
		} else {
			fourKind = 0;
		}
	}
	return fourKind >= 3;
}

bool hasFullHouse(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	bool hasFull = false;
	int temp;
	for (int i = 0; i < 5 && !(hasFull); i++) {
		if (card[i].value == card[i + 1].value && card[i].value == card[i + 2].value) {
			temp = card[i].value;
			for (int j = 0; j < 6 && !(hasFull); j++) {
				if (card[j].value == card[j + 1].value && card[j].value != temp) {
					hasFull = true;
				}
			}
		}
	}
	return hasFull;
}

bool hasFlush(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	int flush = 0;
	for (int i = 0; i < 6 && flush < 4; i++) {
		flush = 0;
		for (int j = 0; j < 7; j++) {
			if (card[i].kind == card[j].kind && j != i) {
				flush++;
			}
		}
	}
	return flush >= 4;
}

bool hasStraight(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	int straight = 0;
	for (int i = 0; i < 6 && straight < 4; i++) {
		if (card[i].value == card[i + 1].value + 1) {
			straight++;
		} else {
			straight = 0;
		}
	}
	return straight >= 4;
}

bool hasThreeOfKind(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	int threeKind = 0;
	for (int i = 0; i < 6 && threeKind < 2; i++) {
		if (card[i].value == card[i + 1].value) {
			threeKind++;
		}
		else {
			threeKind = 0;
		}
	}
	return threeKind >= 2;
}

bool hasTwoPairs(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	int pair = 0;
	for (int i = 0; i < 6 && pair < 2; i++) {
		if (card[i].value == card[i + 1].value) {
			pair++;
		}
	}
	return pair >= 2;
}

bool hasPair(const Card(&card)[PLAY_CARD_NUMBER + HAND_MAX_NUMBER]){
	int pair = 0;
	for (int i = 0; i < 6 && pair < 1; i++) {
		if (card[i].value == card[i + 1].value) {
			pair++;
		}
	}
	return pair >= 1;
}